import { existsSync } from "fs-extra";
import { join } from "path";
import { NotFoundError } from "./error";

export function parseDo(paths: string[], headers: any, query: any) {
    let d = Reflect.get(headers, 'DO') || Reflect.get(headers, 'do')
    if (d) {
        // headers携带了 addon/platform/controller/action
        return { d };
    }
    // headers里没有携带 scope/addon/platform/controller/action
    d = Reflect.get(query, 'D') || Reflect.get(query, 'D')
    if (d) {
        return { d };
    }
    if (paths.length <= 0) {
        return;
    }
    return { d: paths[0] }
}

export function parseAction(paths: string[], headers: any, query: any) {
    let action = Reflect.get(headers, 'ACTION') || Reflect.get(headers, 'action')
    if (action) {
        // headers携带了 addon/platform/controller/action
        const _do = parseDo(paths, headers, query)
        return { action, ..._do };
    }
    // headers里没有携带 scope/addon/platform/controller/action
    action = Reflect.get(query, 'A') || Reflect.get(query, 'a')
    if (action) {
        const _do = parseDo(paths, headers, query);
        return { action, ..._do };
    }
    if (paths.length <= 0) {
        return;
    }
    const [p, ...other] = paths
    const _do = parseDo(other, headers, query)
    action = p;
    return { action: action, ..._do }
}

export function parseController(paths: string[], headers: any, query: any) {
    let scope = Reflect.get(headers, 'CONTROLLER') || Reflect.get(headers, 'controller')
    if (scope) {
        // headers携带了 addon/platform/controller/action
        const action = parseAction(paths, headers, query)
        return { controller: scope, ...action };
    }
    // headers里没有携带 scope/addon/platform/controller/action
    scope = Reflect.get(query, 'C') || Reflect.get(query, 'c')
    if (scope) {
        const action = parseAction(paths, headers, query);
        return { controller: scope, ...action };
    }
    if (paths.length <= 0) {
        return;
    }
    const [p, ...other] = paths
    const action = parseAction(other, headers, query)
    scope = p;
    return { controller: scope, ...action }
}

export function parsePlatform(paths: string[], headers: any, query: any) {
    let scope = Reflect.get(headers, 'PLATFORM') || Reflect.get(headers, 'platform')
    if (scope) {
        // headers携带了 addon/platform/controller/action
        const controller = parseController(paths, headers, query)
        return { platform: scope, ...controller };
    }
    // headers里没有携带 scope/addon/platform/controller/action
    scope = Reflect.get(query, 'P') || Reflect.get(query, 'p')
    if (scope) {
        const controller = parseController(paths, headers, query);
        return { platform: scope, ...controller };
    }
    if (paths.length <= 0) {
        return;
    }
    const [p, ...other] = paths
    const controller = parseController(other, headers, query)
    scope = p;
    return { platform: scope, ...controller }
}
export function parseAddon(paths: string[], headers: any, query: any) {
    let scope = Reflect.get(headers, 'ADDON') || Reflect.get(headers, 'addon')
    if (scope) {
        // headers携带了 addon/platform/controller/action
        const platform = parsePlatform(paths, headers, query)
        return { addon: scope, ...platform };
    }
    // headers里没有携带 scope/addon/platform/controller/action
    scope = Reflect.get(query, 'M') || Reflect.get(query, 'm')
    if (scope) {
        const platform = parsePlatform(paths, headers, query);
        return { addon: scope, ...platform };
    }
    if (paths.length <= 0) {
        return;
    }
    const [p, ...other] = paths
    const platform = parsePlatform(other, headers, query)
    scope = p;
    return { addon: scope, ...platform };
}

export function parseScope(paths: string[], headers: any, query: any) {
    let scope = Reflect.get(headers, 'SCOPE') || Reflect.get(headers, 'scope')
    if (scope) {
        // headers携带了 addon/platform/controller/action
        const addon = parseAddon(paths, headers, query)
        return { scope, ...addon };
    }
    // headers里没有携带 scope/addon/platform/controller/action
    scope = Reflect.get(query, 'S') || Reflect.get(query, 's')
    if (scope) {
        const addon = parseAddon(paths, headers, query);
        return { scope, ...addon };
    }
    if (paths.length <= 0) {
        return;
    }
    const [p, ...other] = paths
    const addon = parseAddon(other, headers, query)
    scope = p;
    return { scope, ...addon }
}
export function parse(paths: string[], headers: any, query: any) {
    return parseScope(paths, headers, query);
}

export function getFilePath(options: { root: string, scope: string, addon: string, platform: string, controller: string, action: string, d: string, method: string }) {
    let root = join(options.root, `addons`, `@${options.scope}`, options.addon, 'dist')
    let filePath = ``
    if (options.platform && options.controller && options.action && options.d) {
        filePath = join(root, options.platform, options.controller, options.action, `${options.d}.${options.method}.js`)
        if (existsSync(filePath)) return filePath;
        filePath = join(root, options.platform, options.controller, options.action, `${options.d}.js`)
        if (existsSync(filePath)) return filePath;
    }
    if (options.platform && options.controller && options.action) {
        filePath = join(root, options.platform, options.controller, `${options.action}.${options.method}.js`)
        if (existsSync(filePath)) return filePath;
        filePath = join(root, options.platform, options.controller, `${options.action}.js`)
        if (existsSync(filePath)) return filePath;
    }
    if (options.platform && options.controller) {
        filePath = join(root, options.platform, `${options.controller}.${options.method}.js`)
        if (existsSync(filePath)) return filePath;
        filePath = join(root, options.platform, `${options.controller}.js`)
        if (existsSync(filePath)) return filePath;
    }
    if (options.platform) {
        filePath = join(root, `${options.platform}.${options.method}.js`)
        if (existsSync(filePath)) return filePath;
        filePath = join(root, `${options.platform}.js`)
        if (existsSync(filePath)) return filePath;
    }
    filePath = join(root, `index.${options.method}.js`)
    if (existsSync(filePath)) return filePath;
    filePath = join(root, `index.js`)
    if (existsSync(filePath)) return filePath
    throw new NotFoundError(`404 not found`);
}